import mitt from 'mitt'
import { onScopeDispose, getCurrentScope } from 'vue'

// 创建全局的 mitt 实例
const globalEmitter = mitt()

/**
 * 基于 mitt 封装的 Hook，提供自动清理功能
 * @returns {Object} 包含 on, once, emit, off, clear 方法的 emitter 对象
 */
export function useMitt() {
  // 存储当前组件注册的所有事件监听器，用于自动清理
  const eventListeners = new Map()

  /**
   * 监听事件
   * @param {string} eventType - 事件类型
   * @param {Function} handler - 事件处理函数
   */
  function on(eventType, handler) {
    globalEmitter.on(eventType, handler)

    // 记录监听器用于自动清理
    if (!eventListeners.has(eventType)) {
      eventListeners.set(eventType, new Set())
    }
    eventListeners.get(eventType).add(handler)
  }

  /**
   * 监听事件，仅触发一次
   * @param {string} eventType - 事件类型
   * @param {Function} handler - 事件处理函数
   */
  function once(eventType, handler) {
    const onceHandler = (data) => {
      // 先执行回调
      handler(data)
      // 然后移除监听器
      off(eventType, onceHandler)
    }

    on(eventType, onceHandler)
  }

  /**
   * 触发事件
   * @param {string} eventType - 事件类型
   * @param {*} data - 要传递的数据
   */
  function emit(eventType, data) {
    globalEmitter.emit(eventType, data)
  }

  /**
   * 移除事件监听
   * @param {string} eventType - 事件类型
   * @param {Function} [handler] - 要移除的特定处理函数（可选）
   */
  function off(eventType, handler) {
    if (handler) {
      globalEmitter.off(eventType, handler)

      // 从记录中移除特定监听器
      const listeners = eventListeners.get(eventType)
      if (listeners) {
        listeners.delete(handler)
        if (listeners.size === 0) {
          eventListeners.delete(eventType)
        }
      }
    } else {
      // 移除该类型的所有监听器
      globalEmitter.all.delete(eventType)
      eventListeners.delete(eventType)
    }
  }

  /**
   * 清除当前组件注册的所有事件监听器
   */
  function clear() {
    for (const [eventType, handlers] of eventListeners.entries()) {
      for (const handler of handlers) {
        globalEmitter.off(eventType, handler)
      }
    }
    eventListeners.clear()
  }

  /**
   * 监听所有事件（通配符监听）
   * @param {Function} handler - 事件处理函数，接收 (eventType, data) 参数
   */
  function all(handler) {
    // mitt 支持通配符 '*' 来监听所有事件
    globalEmitter.on('*', handler)

    // 记录通配符监听器
    if (!eventListeners.has('*')) {
      eventListeners.set('*', new Set())
    }
    eventListeners.get('*').add(handler)
  }

  /**
   * 移除所有事件的监听器或特定的通配符监听器
   * @param {Function} [handler] - 要移除的特定通配符处理函数（可选）
   */
  function offAll(handler) {
    if (handler) {
      globalEmitter.off('*', handler)

      const wildcardHandlers = eventListeners.get('*')
      if (wildcardHandlers) {
        wildcardHandlers.delete(handler)
        if (wildcardHandlers.size === 0) {
          eventListeners.delete('*')
        }
      }
    } else {
      // 移除所有通配符监听器
      globalEmitter.all.delete('*')
      eventListeners.delete('*')
    }
  }

  // 自动清理副作用：当组件卸载时，自动移除该组件注册的所有事件监听器
  if (getCurrentScope()) {
    onScopeDispose(() => {
      clear()
    })
  }

  return {
    on,
    once,
    emit,
    off,
    all,
    offAll,
    clear,
  }
}

/**
 * 获取原始的全局 emitter 实例（用于特殊场景）
 * @returns {Object} 原始的 mitt 实例
 */
export function getGlobalEmitter() {
  return globalEmitter
}

/**
 * 全局清理函数，清除所有事件的所有监听器（谨慎使用）
 */
export function clearAllEvents() {
  globalEmitter.all.clear()
}
